// 演示事件绑定和函数声明中this修正
import React from "react";

export default class EventBind extends React.Component {
  constructor() {
    super()
    this.state = {
      count: 0
    }
    // 为了在回调中使用 this，这个绑定是必不可少的
    // funtiong.prototype.bind() 方法创建一个新的函数，在 bind() 被调用时，这个新函数的 this 被指定为 bind() 的第一个参数，而其余参数将作为新函数的参数，供调用时使用。 参数this是构造器里面的this，它指向类组件实例化对象
    this.handlerCount2 = this.handlerCount2.bind(this)
  }
  // 1. 基本的函数创建
  handlerCount() {
    console.log(this); //undefined, 证明this不指向组件对象，就拿不到setState().所以报错。
    // 如何解决this的指向问题？让它指向组件对象
    this.setState({
      count: this.state.count + 1
    })
  }

  // 2. 解决this的指向方法1：
  // 在 构造器里面，    this.handlerCount = this.handlerCount.bind(this)，绑定this。
  handlerCount2() {
    console.log(this); //EventBind {props: {…}, context: {…}, refs: {…}, updater: {…}, state: {…}, …}
    this.setState({
      count: this.state.count + 1
    })
  }
  // 3. 解决this的指向方法2：添加事件，绑定函数时，使用bind(this)，修改函数里面this的指向

  // 4. 写法3：在 render 中使用 箭头函数

  // 5. 写法4：class 属性（第三阶段提案）,把类里面的函数，写成箭头函数
  handlerCount3 = () => {
    // 方法是个箭头函数，它里面的this指向类中的this（创建这个箭头函数的环境中的this）
    this.setState({
      count: this.state.count + 1
    })
  }
  render() {
    // console.log(this);//EventBind {props: {…}, context: {…}, refs: {…}, updater: {…}, state: {…}, …} 组件实例化对象
    return (
      <div>
        <h1>count: {this.state.count} </h1>
        <button type="button" onClick={this.handlerCount}>+1</button>
        <hr />
        <button type="button" onClick={this.handlerCount2}>1 构造器里面bind(this)</button>

        <button type="button" onClick={this.handlerCount.bind(this)}>2 绑定函数时，使用bind(this)</button>

        <button type="button" onClick={() => {
          // 箭头函数里面的this，指向组件实例化对象
          // console.log(this);//EventBind {props: {…}, context: {…}, refs: {…}, updater: {…}, state: {…}, …} 组件实例化对象
          this.handlerCount() //函数里面调用方法时，要带().
        }}>3 绑定事件时，使用 箭头函数</button>

        <button type="button" onClick={this.handlerCount3}>4 组件的函数用箭头函数写</button>
      </div>
    )
  }
}